package com.huiquan.vocab.job;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.huiquan.dyad.dao.DyadInitDao;
import com.huiquan.framework.constant.BaseContants;
import com.huiquan.framework.utils.FileUtils;
import com.huiquan.management.constant.MigrateCode;
import com.huiquan.management.service.MigrateService;
import com.huiquan.vocab.dao.VocabDyadDao;
import com.huiquan.vocab.dao.VocabDyadRemoveDao;
import com.huiquan.vocab.dao.VocabElementDao;
import com.huiquan.vocab.dao.VocabElementLabelDao;
import com.huiquan.vocab.domain.VocabDyadRemove;
import com.huiquan.vocab.domain.VocabElementLabelResultDto;

@Component
public class DyadJob {

	private static final Logger LOG = LoggerFactory.getLogger(DyadJob.class);

	@Autowired
	private MigrateService migrateService;

	@Autowired
	private VocabDyadDao vocabDyadDao;

	@Autowired
	private VocabElementLabelDao vocabElementLabelDao;
	@Autowired
	private VocabDyadRemoveDao vocabDyadRemoveDao;
	@Autowired
	private VocabElementDao vocabElementDao;
	@Autowired
	private DyadInitDao dyadInitDao;

	/**
	 * <pre>
	 * 通过二元组校验症状正误所需的所有规则需要导出到文件中，每日更新。对应的文件如下：
	 * p+o白名单，附带是否合并属性；
	 * s+de/de+o/si+de 黑名单；
	 * de可以与o组合的列表；
	 * o+in+s/in+s 黑名单；
	 * o+oa remove；
	 * o+in+s remove；
	 * o+o黑名单；
	 * o+o多核心词规则；
	 * o+s黑名单；
	 * o的同义词；
	 * </pre>
	 */
	public void generateDyadRule2File() throws Exception {
		LOG.info("Dyad job generate rule begin!");

		String bakFilePath = migrateService.getBakFilePathByCode(MigrateCode.DYAD_RULE, false);

		// p+o 黑名单
		List<String> pOWhitelist = vocabDyadDao.retrievePOBlacklist4ExportRuleFile();
		FileUtils.generateFile(bakFilePath + File.separator + "p_o_black.txt", StringUtils.join(pOWhitelist, "\n"));

		// p+o合并列表
		List<String> pOMerge = vocabDyadDao.retrievePOMerge4ExportRuleFile();
		FileUtils.generateFile(bakFilePath + File.separator + "p_o_merge.txt", StringUtils.join(pOMerge, "\n"));

		// s+de 黑名单
		List<String> sDeBlacklist = vocabDyadDao.retrieveBlacklist4ExportRuleFile("s+de");
		FileUtils.generateFile(bakFilePath + File.separator + "s_de_black.txt", StringUtils.join(sDeBlacklist, "\n"));

		// si+de 黑名单
		List<String> siDeBlacklist = vocabDyadDao.retrieveBlacklist4ExportRuleFile("si+de");
		FileUtils.generateFile(bakFilePath + File.separator + "si_de_black.txt", StringUtils.join(siDeBlacklist, "\n"));

		// o+de 黑名单
		List<String> oDeBlacklist = vocabDyadDao.retrieveBlacklist4ExportRuleFile("o+de");
		FileUtils.generateFile(bakFilePath + File.separator + "o_de_black.txt", StringUtils.join(oDeBlacklist, "\n"));

		// 可以与o组合的de元素列表
		List<String> deDecorateOlist = vocabElementLabelDao.retrieveDecorateOWord();
		FileUtils.generateFile(bakFilePath + File.separator + "de_decorate_o.txt",
				StringUtils.join(deDecorateOlist, "\n"));

		// o+in+s 黑名单
		List<String> oInSBlacklist = vocabDyadDao.retrieveBlacklist4ExportRuleFile("o+in+s");
		FileUtils.generateFile(bakFilePath + File.separator + "o_in_s_black.txt",
				StringUtils.join(oInSBlacklist, "\n"));

		// in+s 黑名单
		List<String> inSBlacklist = vocabDyadDao.retrieveBlacklist4ExportRuleFile("in+s");
		FileUtils.generateFile(bakFilePath + File.separator + "in_s_black.txt", StringUtils.join(inSBlacklist, "\n"));

		// o+oa remove
		List<String> oOaRemovelist = vocabDyadRemoveDao.retrieveRemove4ExportRuleFile("o+oa");
		FileUtils.generateFile(bakFilePath + File.separator + "o_oa_remove.txt", StringUtils.join(oOaRemovelist, "\n"));

		// o+in+s remove
		List<String> oInSRemovelist = vocabDyadRemoveDao.retrieveRemove4ExportRuleFile("o+in+s");
		FileUtils.generateFile(bakFilePath + File.separator + "o_in_s_remove.txt",
				StringUtils.join(oInSRemovelist, "\n"));

		// o+o黑名单
		List<String> oOBlacklist = vocabDyadDao.retrieveBlacklistAndProp4ExportRuleFile("o+o");
		FileUtils.generateFile(bakFilePath + File.separator + "o_o_black.txt", StringUtils.join(oOBlacklist, "\n"));

		// o+o多核心词规则
		List<String> multiOCombineS = vocabDyadDao.retrieveMultiOCombineS(); // 获取由多个o组成的核心词列表
		FileUtils.generateFile(bakFilePath + File.separator + "multi_o_combine_s.txt",
				StringUtils.join(multiOCombineS, "\n"));

		// o+s黑名单
		List<String> oSBlacklist = vocabDyadDao.retrieveBlacklistAndProp4ExportRuleFile("o+s");
		FileUtils.generateFile(bakFilePath + File.separator + "o_s_black.txt", StringUtils.join(oSBlacklist, "\n"));

		// o的同义词
		List<String> synonymO = vocabDyadDao.retrieveElementSynonymO4ExportRuleFile();
		FileUtils.generateFile(bakFilePath + File.separator + "synonym_o.txt", StringUtils.join(synonymO, "\n"));

		// 替换拆分词语
		FileUtils.generateFile(bakFilePath + File.separator + "element_replace_split.txt", getReplaceMapStr());

		// 可以修饰o的de
		FileUtils.generateFile(bakFilePath + File.separator + "de_decorate_o2.txt", getDeDecorateOStr());

		// o+de二元组
		FileUtils.generateFile(bakFilePath + File.separator + "o_de_dyad.txt", getODeMap());

		// 正确o+o二元组
		FileUtils.generateFile(bakFilePath + File.separator + "o_o_right_dyad.txt", getOOMap());

		// 同义词
		FileUtils.generateFile(bakFilePath + File.separator + "synonymy.txt", getSynonmyStr());

		// remove o+oa
		FileUtils.generateFile(bakFilePath + File.separator + "o_oa_remove2.txt", getRemoveRuleByType("'o+oa'"));

		// remove o+in
		FileUtils.generateFile(bakFilePath + File.separator + "o_in_remove.txt", getRemoveRuleByType("'o+in'"));

		// 错误的p+p
		List<String> ppWrong = vocabDyadDao.retrieveWrongPPArray();
		FileUtils.generateFile(bakFilePath + File.separator + "p_p_wrong.txt", StringUtils.join(ppWrong, "\n"));

		// p+o 合并2
		FileUtils.generateFile(bakFilePath + File.separator + "p_o_merge2.txt", getPOMerge());

		// o+in 黑名单
		List<String> oInBlacklist = vocabDyadDao.retrieveBlacklistAndProp4ExportRuleFile("o+in");
		FileUtils.generateFile(bakFilePath + File.separator + "o_in_black.txt", StringUtils.join(oInBlacklist, "\n"));

		// r 黑名单
		List<String> rBlackList = vocabDyadDao.retrieveBlacklistR();
		FileUtils.generateFile(bakFilePath + File.separator + "r_black.txt", StringUtils.join(rBlackList, "\n"));


		// 调用脚本同步数据
		migrateService.migrateFileByCodeAndBak(MigrateCode.DYAD_RULE, bakFilePath, false);

		LOG.info("Dyad job generate rule end!");
	}

	/**
	 * 获取替换和拆分词语的Str
	 * 
	 * @return
	 */
	private String getReplaceMapStr() {
		// 获取替换词
		List<Map<String, String>> replaceList = vocabElementDao.retrieveElementReplace();
		// 获取拆分
		List<Map<String, String>> splitList = vocabElementDao.retrieveElementSplit();
		replaceList.addAll(splitList);
		StringBuffer str = new StringBuffer();
		for (Map<String, String> replace : replaceList) {
			str.append(replace.get("original")).append((char) 1 + "").append(replace.get("result")).append("\n");
		}
		return str.toString();
	}

	/**
	 * 查找可以修饰o的de
	 * 
	 * @return
	 */
	private String getDeDecorateOStr() {
		// 初始化修饰o的de的表
		vocabElementLabelDao.init();
		Map<String, Object> param = new HashMap<>();
		param.put("isDecorateO", 1);
		StringBuffer str = new StringBuffer();
		List<VocabElementLabelResultDto> labelResult = vocabElementLabelDao.retrieveResultList(param);
		for (VocabElementLabelResultDto result : labelResult) {
			str.append(result.getElement()).append("\n");
		}
		return str.toString();
	}

	private String getODeMap() {
		// 查询所有的o+de二元组
		List<Map<String, String>> odeAll = dyadInitDao.retrieveOdeCombine();
		StringBuffer str = new StringBuffer();
		for (Map<String, String> ode : odeAll) {
			str.append(ode.get("array")).append((char) 1 + "").append(ode.get("std")).append((char) 1 + "")
					.append(ode.get("part_pattern")).append((char) 1 + "").append(ode.get("flag")).append((char) 1 + "")
					.append(ode.get("combine_s")).append("\n");
		}
		return str.toString();
	}

	private String getPOMerge() {
		// 查询所有的o+de二元组
		List<Map<String, String>> odeAll = dyadInitDao.retrievePOMerge();
		StringBuffer str = new StringBuffer();
		for (Map<String, String> ode : odeAll) {
			str.append(ode.get("id")).append((char) 1 + "").append(ode.get("array")).append((char) 1 + "")
					.append(ode.get("std")).append((char) 1 + "").append(ode.get("part_pattern")).append("\n");
		}
		return str.toString();
	}

	private String getOOMap() {
		// 查询所有的o+o二元组
		List<Map<String, String>> ooAll = dyadInitDao.retrieveOOCombine();
		StringBuffer str = new StringBuffer();
		for (Map<String, String> oo : ooAll) {
			str.append(oo.get("array")).append((char) 1 + "").append(oo.get("std")).append((char) 1 + "")
					.append(oo.get("part_pattern")).append((char) 1 + "").append(oo.get("flag")).append((char) 1 + "")
					.append(oo.get("combine_s")).append("\n");
		}
		return str.toString();
	}

	/**
	 * 获取同义词~同义词o ,oa若判定为相同,属性可以忽略
	 * 
	 * @return
	 */
	private String getSynonmyStr() {
		// 忽略o 和 oa的同义词,如果他们两个相同的话
		List<Map<String, String>> synonymys = dyadInitDao.retrieveDyadSynonymy();
		StringBuffer str = new StringBuffer();
		for (Map<String, String> synonymy : synonymys) {
			String property = synonymy.get("property");
			String word = synonymy.get("word");
			String std = synonymy.get("std");
			str.append(property).append((char) 1 + "").append(word).append((char) 1 + "").append(std).append("\n");
		}
		return str.toString();
	}

	private String getRemoveRuleByType(String type) {
		Map<String, Object> param1 = new HashMap<>();
		param1.clear();
		param1.put("removeFlag", BaseContants.FLAG_YES);
		param1.put("types", type);
		param1.put("orderStr", "CHAR_LENGTH(part_pattern) desc");
		List<VocabDyadRemove> firstRemoveList = vocabDyadRemoveDao.retrieveList(param1);
		StringBuffer str = new StringBuffer();
		for (VocabDyadRemove firstRemove : firstRemoveList) {
			str.append(firstRemove.getArray()).append((char) 1 + "").append(firstRemove.getPartPattern())
					.append((char) 1 + "").append(firstRemove.getResultArray()).append((char) 1 + "")
					.append(firstRemove.getResultPattern()).append((char) 1 + "").append(firstRemove.getType())
					.append("\n");
		}
		return str.toString();
	}
}
